/*
 * @author: wizardc
 */

using System;
using Dou.Clock;
using Dou.Timer;
using UnityEngine;

namespace Dou.ScreenController
{
    /// <summary>
    /// 屏幕管理器
    /// </summary>
    public sealed class ScreenManager : IClockClient
    {
        
#if UNITY_EDITOR

        public static bool GameViewIsSimulator()
        {
            var playModeViewType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.PlayModeView");
            var getRenderingViewMethod = playModeViewType.GetMethod("GetMainPlayModeView", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
            var renderingViewValue = getRenderingViewMethod.Invoke(null, null);
            if (renderingViewValue != null)
            {
                var curView = renderingViewValue.GetType().Name;
                if (curView == "SimulatorWindow")
                {
                    return true;
                }
            }
            return false;
        }

#endif
        
        private static ScreenManager _instance;
        public static ScreenManager instance => _instance ??= new ScreenManager();

        /// <summary>
        /// 屏幕旋转模式改变时，参数 true 表示横屏 false 表示竖屏
        /// 注：手动改变时也会抛出该事件
        /// </summary>
        public event Action<bool> onScreenIsLandscapeChanged;
        
        private ScreenMode _mode = ScreenMode.Auto;
        // 当前是否是横屏
        private bool _isLandscape = false;
        
        private ScreenManager()
        {
        }

        /// <summary>
        /// 当前的屏幕旋转模式
        /// </summary>
        public ScreenMode mode
        {
            set
            {
                if (_mode != value)
                {
                    _mode = value;
                    ApplyScreenMode();
                }
            }
            get => _mode;
        }

        /// <summary>
        /// 当前是否是横屏
        /// </summary>
        public bool isLandscape => _isLandscape;
        
        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            ClockUtil.realTimeClock.AddClient(this);

            ApplyScreenMode();
            _isLandscape = GetScreenIsLandscape();
        }

        private void ApplyScreenMode()
        {
            switch (_mode)
            {
                case ScreenMode.Auto:
                    Screen.orientation = ScreenOrientation.AutoRotation;
                    Screen.autorotateToPortrait = true;
                    Screen.autorotateToPortraitUpsideDown = false;
                    Screen.autorotateToLandscapeLeft = true;
                    Screen.autorotateToLandscapeRight = true;
                    break;
                case ScreenMode.Landscape:
                    Screen.orientation = ScreenOrientation.AutoRotation;
                    Screen.autorotateToPortrait = false;
                    Screen.autorotateToPortraitUpsideDown = false;
                    Screen.autorotateToLandscapeLeft = true;
                    Screen.autorotateToLandscapeRight = true;
                    break;
                case ScreenMode.Portrait:
                    Screen.orientation = ScreenOrientation.Portrait;
                    Screen.autorotateToPortrait = true;
                    Screen.autorotateToPortraitUpsideDown = false;
                    Screen.autorotateToLandscapeLeft = false;
                    Screen.autorotateToLandscapeRight = false;
                    break;
            }
        }

        private bool GetScreenIsLandscape()
        {
#if UNITY_EDITOR
            return Screen.width > Screen.height;
#else
            return Screen.orientation == ScreenOrientation.LandscapeLeft || Screen.orientation == ScreenOrientation.LandscapeRight;
#endif
        }

        public void Update(float passedTime)
        {
            var isLandscape = GetScreenIsLandscape();
            if (isLandscape != _isLandscape)
            {
                _isLandscape = isLandscape;
                onScreenIsLandscapeChanged?.Invoke(_isLandscape);
            }
        }
    }
}
